#pragma once
#ifndef __PROJECT_ITEM__INCLUDED__HH__
#define __PROJECT_ITEM__INCLUDED__HH__

#include <qtreewidget.h>
#include <boost\any.hpp>
#include "ProjectItemTypes.h"
#include <LitMovable.h>

class ProjectNode
{
public:
	typedef ProjectNodeType		Type;
	typedef QTreeWidgetItem		Item;
	typedef QTreeWidgetItem*	ItemPtr;

	ProjectNode( ItemPtr item = NULL, Type type = PNT_UNKNOWN, Lit::MovablePtr mov = Lit::MovablePtr() );
	~ProjectNode( );
	
	bool				isType( Type t ) const;
	Type				type( ) const;
	std::string			typeStr() const;
	ItemPtr				item() const;
	std::string			getName() const;
	Lit::MovablePtr		movable() const;
	void				setMovable( Lit::MovablePtr mov );
	void				unlinkItem( );
protected:
	ItemPtr				mItem;
	ProjectNodeType		mType;
	Lit::MovablePtr		mMovable;
};

typedef Lit::RefPtr<ProjectNode> ProjectNodePtr;

class ProjectStructure
{
public: 
	/*********************** Typedefs ************************/
	typedef QTreeWidget						TreeType;
	typedef ProjectNode						Node;
	typedef ProjectNodePtr					NodePtr;
	typedef std::map<std::string, NodePtr>	NodeMap;
	/*********************** Typedefs ************************/
	
public:
	/*********************** Members ************************/
	ProjectStructure( const std::string &projectName, TreeType * tree );
	ProjectStructure( );
	ProjectStructure( const ProjectStructure& rk );
	virtual ~ProjectStructure( );
	
	NodeMap& nodes();
	const NodeMap& nodes() const;

	void setup( const std::string &projectName, TreeType * tree  );
	ProjectNodePtr rootNode() const;
	ProjectNodePtr entitiesNode() const;
	ProjectNodePtr lightsNode() const;
	ProjectNodePtr soundsNode() const;

	ProjectNodePtr createTopLevelNode( const std::string &name );
	ProjectNodePtr createFolder( const std::string &name, ProjectNodePtr parentNode = NULL );
	ProjectNodePtr createNode( const std::string &name, Node::Type type, Lit::MovablePtr mov=Lit::MovablePtr(), ProjectNodePtr parentNode = NULL );

	Node::ItemPtr fromItemName( const std::string &name );
	Node::ItemPtr fromMovable( Lit::MovablePtr mov );

	bool hasNode( Node::ItemPtr n ) const;
	NodePtr findNode( Node::ItemPtr n ) const;
	NodePtr getNode( Node::ItemPtr n ) const;
	
	void _destroyNode( NodePtr & node, bool unlink );
	void destroyNodes( );
	void destroyNode( Node::ItemPtr n );
	void eraseNode( Node::ItemPtr n );

protected:
	NodePtr			mRoot;
	NodePtr			mLights;
	NodePtr			mEntities;
	NodePtr			mSounds;
	TreeType*		mTree;
	NodeMap			mNodes;
};


#endif